﻿using System;
using System.ComponentModel;
using ProjectEuler.Linq;

namespace ProjectEuler.Problems
{
    [EulerProblem(31, 73682)]
    [Description("Investigating combinations of English currency denominations.")]
    internal sealed class Problem031 : EulerProblem
    {
        public override Object Solve()
        {
            return CombinationGenerator(0)(200);
        }

        private static Func<Int32, Int32> CombinationGenerator(Int32 coin)
        {
            return remaining =>
            {
                var value = Coins[coin];

                if (value == 1)
                {
                    return 1;
                }

                if (remaining >= 0)
                {
                    return
                        CombinationGenerator(coin)(remaining - value) +
                        CombinationGenerator(coin + 1)(remaining);
                }

                return 0;
            };
        }

        private static readonly Int32[] Coins = new[] { 200, 100, 50, 20, 10, 5, 2, 1 };
    }
}
